/**
 * LinkedQueue
 */
define('utils/LinkedQueue', null, function() {

function Node(data, next) {
    this.data = data;
    this.next = next;
}

function LinkedQueue() {
    this.headNode = null;
    this.tailNode = null;
    this.size = 0;
    this.currentIteratorNode = null;
}

LinkedQueue.prototype.iterator = function () {
    if (null === this.currentIteratorNode) {
        this.currentIteratorNode = this.headNode;
    }
    else {
        this.currentIteratorNode = this.currentIteratorNode.next;
    }
    return null === this.currentIteratorNode
        ? (this.currentIteratorNode = null, null)
        : this.currentIteratorNode.data;
};

LinkedQueue.prototype.each = function (callback) {
    for (var current = this.headNode; null !== current; current = current.next) {
        if (false === callback(current.data)) {
            break;
        }
    }
};

LinkedQueue.prototype.add = function (data) {
    var node = new Node(data, null);
    if (0 === this.size) {
        this.headNode = node;
    }
    else {
        this.tailNode.next = node;
    }
    this.tailNode = node;
    this.size++;
};

LinkedQueue.prototype.take = function () {
    // 为空直接返回
    if (0 === this.size) {
        return null;
    }
    var data = this.headNode.data;
    var tmpHeadNode = this.headNode;
    // 从队列去除头节点
    this.headNode = tmpHeadNode.next;
    tmpHeadNode.next = null;
    tmpHeadNode = null;
    // 没节点了
    if (null === this.headNode) {
        this.headNode = this.tailNode = null;
    }
    this.size--;
    return data;
};

LinkedQueue.prototype.remove = function (data) {
    var current = this.headNode;
    var previous = null;
    for (; null !== current; previous = current, current = current.next) {
        if (data !== current.data) {
            continue;
        }
        // 删除头结点
        if (null === previous) {
            this.headNode = current.next;
        }
        // 非头结点需要移动 previous
        if (null !== previous) {
            previous.next = current.next;
        }
        // 尾节点
        if (null === current.next) {
            this.tailNode = previous;
        }
        // 清除当前节点
        current.next = null;
        current = null;
        this.size--;
        break;
    }
};

LinkedQueue.prototype.clear = function () {
    while (0 !== this.size) {
        this.take();
    }
};

LinkedQueue.prototype.toString = function () {
    var str = '[ ';
    for (var current = this.headNode; null !== current; current = current.next) {
        str += current.data + ' ';
    }
    return str + ' ]';
};

return LinkedQueue;
});
